//
// Created by wangyz38535 on 2021/9/27.
//

#include "vector_list.h"


/**
 * @brief 内部封装一个vector
 * @tparam T
 * @param initialCapacity
 */
template<typename T>
VectorList<T>::VectorList(int initialCapacity) {
    if (initialCapacity < 1) {
        cout << "initialCapacity must be > 0, initialCapacity = " << initialCapacity << endl;
        throw MyException("Initial capacity invalid.");
    }
    // 创建vector用于记录数据
    m_element = new vector<T>;
    // 按照指定能力初始化vector
    m_element->reserve(initialCapacity);
}

template<typename T>
VectorList<T>::VectorList(const VectorList <T> &theList) {
    // copy 构造函数
    m_element = new vector<T>(*theList.m_element);
}

template<typename T>
T &VectorList<T>::Get(int theIndex) const {
    // 如果没有对应的元素就抛出异常
    CheckIndex(theIndex);
    return (*m_element)[theIndex];
}

template<typename T>
int VectorList<T>::IndexOf(const T &theElement) const {
    // search for the element
    auto theIndex = static_cast<int>(find(m_element->begin(), m_element->end(), theElement) - m_element->begin());

    // 检查是否查询到数据
    if (theIndex == Size()) {
        // 没有找到
        return ARRAY_ERROR;
    } else {
        return ARRAY_OK;
    }
}

template<typename T>
void VectorList<T>::Erase(int theIndex) {
    // 先检查 Index是否合法
    CheckIndex(theIndex);
    m_element->erase(m_element->begin() + theIndex);
}

template<typename T>
void VectorList<T>::Insert(int theIndex, const T &theElement) {
    CheckIndex(theIndex);
    // vector 支持迭代器跳跃级增加
    m_element->insert(m_element->begin() + theIndex, theElement);
}

template<typename T>
void VectorList<T>::Output(ostream &out) const {
    // copy list data to stream out
    copy(m_element->begin(), m_element->end(), ostream_iterator<T>(out, " "));
}

template<typename T>
ostream &operator<<(ostream &out, const VectorList<T> &x) {
    x.Output(out);
    return out;
}

template<typename T>
void VectorList<T>::CheckIndex(int theIndex) const {
    if (theIndex < 0 || theIndex >= Size()) {
        cout << "Index = " << theIndex << " size = " << Size() <<endl;
        throw MyException("Index is invalid.");
    }
}


